﻿using System.Collections;
using System.Globalization;
using System.Reflection;

namespace LS.Screening.UI.Common
{
    /// <summary>
    /// 枚举帮助类
    /// 枚举信息,如果枚举为BoolEnum,Key值请绑定Key,如果为Enum,Key值请绑定Value
    /// </summary>
    public static class EnumHelper
    {
        private static Dictionary<Type, EnumDescription> enumDescriptions = new Dictionary<Type, EnumDescription>();

        /// <summary>
        /// 清除所有枚举描述信息数据 一般在切换语言后需要清理，以便重新获取对应语言的描述信息
        /// </summary>
        public static void Clear()
        {
            enumDescriptions = new Dictionary<Type, EnumDescription>();
        }

        /// <summary>
        /// 查询枚举描述信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static EnumDescription GetDescription<T>()
        {
            return GetDescription(typeof(T));
        }

        /// <summary>
        /// 得到枚举值的说明信息
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetDescription(object enumValue)
        {
            if (enumValue == null)
            {
                return null;
            }

            Type type = enumValue.GetType();
            if (type.IsNullableType())
            {
                type = Nullable.GetUnderlyingType(type);
            }

            if (!type.IsEnum)
            {
                throw new Exception("enumValue is not enum type");
            }

            EnumDescription description = GetDescription(type);
            int key = (int)enumValue;
            return description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Key == key).Description;
        }

        /// <summary>
        /// 获取枚举描述信息
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetDisplay(this Enum enumValue)
        {
            Enum enumValue2 = enumValue;
            if (enumValue2 == null)
            {
                return null;
            }

            Type type = enumValue2.GetType();
            if (type.IsNullableType())
            {
                type = Nullable.GetUnderlyingType(type);
            }

            if (!type.IsEnum)
            {
                throw new Exception("enumValue is not enum type");
            }

            EnumDescription description = GetDescription(type);
            return description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Value.Equals(enumValue2)).Description;
        }

        /// <summary>
        /// 获取枚举描述信息
        /// </summary>
        /// <param name="enumType"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static EnumDescription GetDescription(Type enumType)
        {
            Type enumType2 = enumType;
            if (enumType2.IsNullableType())
            {
                enumType2 = Nullable.GetUnderlyingType(enumType2);
            }

            if (enumType2 == null || !enumType2.IsEnum)
            {
                throw new Exception("enumType");
            }

            if (enumDescriptions.ContainsKey(enumType2))
            {
                EnumDescription obj = enumDescriptions[enumType2];
                obj = obj.ToJson().ToObject<EnumDescription>();
                obj.EnumItemDescriptions.ForEach(delegate (EnumItemDescription a)
                {
                    a.Selected = false;
                    a.Value = Enum.ToObject(enumType2, a.Key);
                });
                return obj;
            }

            EnumDescription enumDescription = new EnumDescription();
            enumDescription.TypeFullName = enumType2.Assembly.GetName().Name + "," + enumType2.FullName;
            enumDescription.Description = enumType2.GetDisplay();
            if (string.IsNullOrEmpty(enumDescription.Description))
            {
                enumDescription.Description = enumType2.Name;
            }

            List<FieldInfo> list = ((TypeInfo)enumType2).DeclaredFields.ToList();
            for (int i = 0; i < list.Count; i++)
            {
                FieldInfo fieldInfo = list[i];
                if (!(fieldInfo.Name == "value__"))
                {
                    EnumItemDescription enumItemDescription = new EnumItemDescription();
                    enumItemDescription.Description = fieldInfo.GetDisplay();
                    if (string.IsNullOrEmpty(enumItemDescription.Description))
                    {
                        enumItemDescription.Description = fieldInfo.Name;
                    }
                    enumItemDescription.Value = fieldInfo.GetValue(null);
                    enumItemDescription.Key = (int)enumItemDescription.Value;
                    enumDescription.EnumItemDescriptions.Add(enumItemDescription);
                }
            }

            enumDescription.EnumItemDescriptions = enumDescription.EnumItemDescriptions.OrderBy((EnumItemDescription p) => p.Key).ToList();
            enumDescriptions.Add(enumType2, enumDescription);
            return enumDescription;
        }

        /// <summary>
        /// 通过枚举类型全名称[AssemblyName,TypeFullName]，获取枚举描述信息
        /// </summary>
        /// <param name="enumTypeFullName"></param>
        /// <returns></returns>
        public static EnumDescription GetDescription(string enumTypeFullName)
        {
            string[] array = enumTypeFullName.Split(',', ';');
            Type type = TypeHelper.GetType(array[0], array[1]);
            return GetDescription(type);
        }

        /// <summary>
        /// 获取单个枚举项的描述信息
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static EnumItemDescription GetItemDescription(object enumValue)
        {
            return GetItemDescriptions(enumValue).FirstOrDefault();
        }

        /// <summary>
        /// 获取多个枚举项的描述信息
        /// </summary>
        /// <param name="enumValues"></param>
        /// <returns></returns>
        public static List<EnumItemDescription> GetItemDescriptions(IList enumValues)
        {
            if (enumValues == null || enumValues.Count == 0)
            {
                throw new Exception("参数[enumValues]不能为空");
            }
            List<EnumItemDescription> list = new List<EnumItemDescription>();
            foreach (object enumValue in enumValues)
            {
                EnumItemDescription itemDescription = GetItemDescription(enumValue);
                list.Add(itemDescription);
            }
            return list;
        }

        /// <summary>
        /// 获取多个枚举项的描述信息
        /// </summary>
        /// <param name="enumValues"></param>
        /// <returns></returns>
        public static List<EnumItemDescription> GetItemDescriptions(params object[] enumValues)
        {
            object[] enumValues2 = enumValues;
            if (enumValues2 == null || enumValues2.Length == 0)
            {
                throw new Exception("参数[enumValues]不能为空");
            }

            Type type = enumValues2[0].GetType();
            if (!(type == null) && !type.IsArray && type.FullName.StartsWith("System.Nullable`1["))
            {
                type = Nullable.GetUnderlyingType(type);
            }

            if (!type.IsEnum)
            {
                throw new Exception("参数[enumValues]中的项必须为枚举类型");
            }
            EnumDescription description = GetDescription(type);
            return description.EnumItemDescriptions.Where((EnumItemDescription p) => enumValues2.Any((object t) => t.Equals(p.Value))).ToList();
        }

        /// <summary>
        /// 获取多个枚举项的描述信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<EnumItemDescription> GetItemDescriptions<T>()
        {
            return GetDescription<T>().EnumItemDescriptions;
        }

        /// <summary>
        /// 获取多个枚举项的描述信息
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static List<EnumItemDescription> GetItemDescriptions(Type type)
        {
            return GetDescription(type).EnumItemDescriptions;
        }

        /// <summary>
        /// 通过枚举描述信息，得到枚举值
        /// </summary>
        /// <param name="enumType"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        public static object GetValueByDescription(Type enumType, string description)
        {
            string description2 = description;
            EnumDescription description3 = GetDescription(enumType);
            return description3.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Description == description2)?.Value;
        }

        /// <summary>
        /// 通过枚举描述信息，得到枚举值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="description"></param>
        /// <returns></returns>
        public static object GetValueByDescription<T>(string description)
        {
            string description2 = description;
            EnumDescription description3 = GetDescription(typeof(T));
            return description3.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Description == description2)?.Value;
        }

        /// <summary>
        /// 枚举值字符串转换成Int列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strValues"></param>
        /// <returns></returns>
        public static T[] ConvertToArray<T>(string strValues)
        {
            if (string.IsNullOrEmpty(strValues))
            {
                return null;
            }
            EnumDescription description = GetDescription<T>();
            List<T> list = new List<T>();
            string[] array = strValues.Split(',');
            string[] array2 = array;
            foreach (string text in array2)
            {
                string s = text.Trim();
                EnumItemDescription enumItemDescription = description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Value.ToString() == s || p.Key.ToString() == s);
                if (enumItemDescription != null)
                {
                    list.Add((T)enumItemDescription.Value);
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 枚举值字符串转换成Int列表
        /// </summary>
        /// <param name="strValues"></param>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static object[] ConvertToArray(string strValues, Type enumType)
        {
            if (string.IsNullOrEmpty(strValues))
            {
                return null;
            }
            EnumDescription description = GetDescription(enumType);
            List<object> list = new List<object>();
            string[] array = strValues.Split(',');
            string[] array2 = array;
            foreach (string text in array2)
            {
                string s = text.Trim();
                EnumItemDescription enumItemDescription = description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Value.ToString() == s || p.Key.ToString() == s);
                if (enumItemDescription != null)
                {
                    list.Add(enumItemDescription.Value);
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 枚举数据转换成字符串，以","分隔多个值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumValues"></param>
        /// <returns></returns>
        public static string ConvertToString<T>(params T[] enumValues)
        {
            if (enumValues == null || enumValues.Count() == 0)
            {
                return string.Empty;
            }
            string text = string.Empty;
            EnumDescription description = GetDescription(typeof(T));
            for (int i = 0; i < enumValues.Length; i++)
            {
                T e = enumValues[i];
                EnumItemDescription enumItemDescription = description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Value.ToString().Equals(e.ToString()));
                if (enumItemDescription != null)
                {
                    if (!string.IsNullOrEmpty(text))
                    {
                        text += ",";
                    }
                    text += enumItemDescription.Value.ToString();
                }
            }
            return text;
        }

        /// <summary>
        /// 枚举数据转换成字符串，以","分隔多个值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumValues"></param>
        /// <returns></returns>
        public static string ConvertToValueStr<T>(params T[] enumValues)
        {
            if (enumValues == null || enumValues.Count() == 0)
            {
                return string.Empty;
            }
            string text = string.Empty;
            EnumDescription description = GetDescription(typeof(T));
            for (int i = 0; i < enumValues.Length; i++)
            {
                T e = enumValues[i];
                EnumItemDescription enumItemDescription = description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Value.ToString().Equals(e.ToString()));
                if (enumItemDescription != null)
                {
                    if (!string.IsNullOrEmpty(text))
                    {
                        text += ",";
                    }
                    text += enumItemDescription.Value.ToString();
                }
            }
            return text;
        }

        /// <summary>
        /// 枚举数据转换成字符串，以","分隔多个值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumValues"></param>
        /// <returns></returns>
        public static string ConvertToKeyStr<T>(params T[] enumValues)
        {
            if (enumValues == null || enumValues.Count() == 0)
            {
                return string.Empty;
            }
            string text = string.Empty;
            EnumDescription description = GetDescription(typeof(T));
            for (int i = 0; i < enumValues.Length; i++)
            {
                T e = enumValues[i];
                EnumItemDescription enumItemDescription = description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Key.ToString().Equals(e.ToString()));
                if (enumItemDescription != null)
                {
                    if (!string.IsNullOrEmpty(text))
                    {
                        text += ",";
                    }
                    text += enumItemDescription.Key;
                }
            }
            return text;
        }

        /// <summary>
        /// 枚举数据转换成字符串，以","分隔多个值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumValues"></param>
        /// <returns></returns>
        public static string ConvertToDescription<T>(params T[] enumValues)
        {
            return ConvertToDescription(",", enumValues);
        }

        /// <summary>
        /// 枚举数据转换成字符串，以指定字符分隔多个值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="spliteChar">分隔符</param>
        /// <param name="enumValues">枚举数组</param>
        /// <returns></returns>
        public static string ConvertToDescription<T>(string spliteChar, params T[] enumValues)
        {
            if (enumValues == null || enumValues.Count() == 0)
            {
                return string.Empty;
            }
            string text = string.Empty;
            EnumDescription description = GetDescription(typeof(T));
            for (int i = 0; i < enumValues.Length; i++)
            {
                T e = enumValues[i];
                EnumItemDescription enumItemDescription = description.EnumItemDescriptions.FirstOrDefault((EnumItemDescription p) => p.Value.ToString().Equals(e.ToString()));
                if (enumItemDescription != null)
                {
                    if (!string.IsNullOrEmpty(text))
                    {
                        text += spliteChar;
                    }
                    text += enumItemDescription.Description;
                }
            }
            return text;
        }

        /// <summary>
        /// 返回Title-Case字符串(字符串首字母大写)
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static string ToTitleCase<TEnum>(this TEnum t) where TEnum : Enum
        {
            return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(t.ToString());
        }

        /// <summary>
        /// 返回Pascal-Case字符串(单词首字母大写)
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static string ToPascalCase<TEnum>(this TEnum t) where TEnum : Enum
        {
            if (t == null)
            {
                return null;
            }
            string text = t.ToString();
            char[] array = text.ToCharArray();
            array[0] = char.ToUpper(array[0]);
            return new string(array);
        }

        /// <summary>
        /// 返回Camel-Case字符串（单词首字母小写）
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static string ToCamelCase<TEnum>(this TEnum t) where TEnum : Enum
        {
            if (t == null)
            {
                return null;
            }
            string text = t.ToString();
            char[] array = text.ToCharArray();
            array[0] = char.ToLower(array[0]);
            return new string(array);
        }
    }
}
